%% Allan deviation
%  Version : v1.0
%  Author  : E. Ogier
%  Release : 13th april 2015

classdef AVAR_GUI < hgsetget
   
    properties
        Source = '';                    % Source
        Period = 1;                     % Sampling period
        Unit   = 's';                   % Sampling unit
        Variable = '';                  % Signal variable
        Time_value = 100;               % Integration times parameter
        Time_definition = 'Sampling';   % Integration times mode
        Mode = 'ADEV';                  % Deviation mode
        Overlapping = false;            % Mode overlapping or non-overlapping
        Abscissa = '\tau';              % Plot abscissa
        Ordinate = '\sigma';            % Plot ordinate
        Template = 'all';               % Noise template coefficients
        ADEV = ...                      % Allan variance data structure :
            struct('Tau',      [],...   % - integration times
                   'ADEV',     [],...   % - Allan deviation
                   'Template', [],...   % - Noise template
                   'Sum',      [],...   % - Sum of noise templates
                   'Data',     []);     % - Noise characteristics  
        Interruption = false;           % Interruption status        
    end
    
    methods
        
        % Constructor
        function Object = AVAR_GUI(varargin)
                
            if isempty(findall(0,'Type','Figure','-and','Tag','AVAR'))
                AVAR();
            end
            
            for v = 1:2:length(varargin)
                Property = varargin{v};
                Value = varargin{v+1};
                set(Object,Property,Value); 
            end         
            
        end
        
        % Function 'set'
        function Object = set(Object,varargin)
            
            global A Tau ADEV
            
            % Handles
            Figure = findall(0,'type','figure','-and','tag','AVAR');
            handles = guidata(Figure);
            
            % Properties and values
            Properties = varargin(1:2:end);
            Values = varargin(2:2:end);
            
            for n = 1:length(Properties)
                
                [is, Property] = isproperty(Object,Properties{n});
                if is
                    Object.(Property) = Values{n};
                else
                    error('Property "%s" not supported !',Properties{n});
                end
                
                Value = Values{n};
                
                switch strrep(lower(Property),'_','')
                    
                    case 'source'
                        set(handles.Field_source,'string',Value);                        
                        Data = matfile(Value);
                        List = setdiff(fieldnames(Data),'Properties');
                        if isempty(List)
                            List = ' ';
                        end
                        set(handles.Popupmenu_source,'String',List);
                        
                    case 'period'
                        set(handles.Field_period,'string',Value);
                        
                    case 'unit'
                        Units = get(handles.Popupmenu_unit,'string');
                        [Boolean,Index] = ismember(lower(Value),Units);
                        if ~Boolean
                           error('Unit [%s] not enable.');
                        end
                        set(handles.Popupmenu_unit,'Value',Index);
                        
                    case 'timevalue'
                        set(handles.Field_times,'String',Value);
                     
                    case 'timedefinition'
                        switch lower(Value)
                            case 'vector'
                                set(handles.Checkbox_user_defined_vector,'Value',1);                        
                                set(handles.Checkbox_number_of_samples,  'Value',0);
                            case 'sampling'
                                set(handles.Checkbox_user_defined_vector,'Value',0);                        
                                set(handles.Checkbox_number_of_samples,  'Value',1);
                        end
                        
                    case 'mode'
                        switch upper(Value)
                            case 'ADEV'
                                set(handles.Popupmenu_mode,'Value',1);
                            case 'MDEV'                                
                                set(handles.Popupmenu_mode,...
                                    'String',{'Allan deviation','Modified deviation','Time deviation'},...
                                    'Value',2);
                            case 'TDEV'                                
                                set(handles.Popupmenu_mode,...                                    
                                    'String',{'Allan deviation','Modified deviation','Time deviation'},...
                                    'Value',3);
                        end
                        Figure = findall(0,'type','figure','-and','tag','AVAR');
                        handles = guidata(Figure);
                        AVAR('Popupmenu_mode_Callback',handles.Popupmenu_mode, [], handles);
                        
                    case 'overlapping'
                        if Value
                            set(handles.Checkbox_overlapping,    'Value',1);                        
                            set(handles.Checkbox_non_overlapping,'Value',0);
                        else                            
                            set(handles.Checkbox_overlapping,    'Value',0);                        
                            set(handles.Checkbox_non_overlapping,'Value',1);
                        end
                        AVAR('Memorization',handles);
                        
                    case 'abscissa'
                        set(handles.Abscissa,'String',Value);
                        
                    case 'ordinate'
                        set(handles.Ordinate,'String',Value);
                        
                    case 'template'
                        Checkboxes = {'Checkbox_1','Checkbox_2','Checkbox_3','Checkbox_4','Checkbox_5'};
                        for c = 1:numel(Checkboxes)                         
                            set(handles.(Checkboxes{c}),'Value',0);
                        end                        
                        A = Function_template(Value);  
                        if ~isempty(ADEV)
                            Inputs.Tau = Tau;
                            Inputs.ADEV = ADEV;
                            Inputs.A = A;
                            AVAR('Template',Inputs,handles);
                        end
                        
                end
                
            end
            
            % Template
            function A = Function_template(Value_checkbox)
                
                switch class(Value_checkbox)
                    case 'char'
                        switch lower(Value_checkbox)
                            case 'all'                                
                                A = [-1 -0.5 0 +0.5 +1];
                                Function_template(A);
                            otherwise, error('Value %s is ioncorrect.',Value_checkbox);
                        end
                    case 'double'
                        A = Value_checkbox;
                        if isscalar(Value_checkbox)
                            switch Value_checkbox
                                case -1,   set(handles.Checkbox_1,'Value',1);
                                case -0.5, set(handles.Checkbox_2,'Value',1);
                                case  0,   set(handles.Checkbox_3,'Value',1);
                                case +0.5, set(handles.Checkbox_4,'Value',1);
                                case +1,   set(handles.Checkbox_5,'Value',1);
                            end
                        else
                            for v = 1:numel(Value_checkbox)
                                Function_template(Value_checkbox(v));
                            end
                        end
                end
                
            end
            
        end
        
        % Function 'get'
        function Value = get(Object,Property)
            
            [is, Property] = isproperty(Object,Property);
            if ~is
                error('Property "%s" not supported !',Property);
            end
            
            Figure = findall(0,'type','figure','-and','tag','AVAR');
            
            switch lower(Property)
                case 'adev'
                    Value = GetData(Figure);
                case 'interruption'
                    handles = guidata(Figure);
                    Value = handles.Bar.Interruption;
                otherwise
                    Value = Object.(Property);
            end
            
        end
        
        % Function 'ispropery'
        function [is, Property] = isproperty(Object,Property)
            Property
            Properties = fieldnames(Object); 
            [is, b] = ismember(lower(Property),strrep(lower(Properties),'_',''));
            Property = Properties{b};
            
        end
        
        % Function 'convert'
        function Object = start(Object)
            
            Figure = findall(0,'type','figure','-and','tag','AVAR');                
            handles = guidata(Figure);  
            AVAR('Button_start_stop_Callback',handles.Button_start_stop, [], handles);
            
        end
        
    end
    
end

% Get Allan variance data
function ADEVs = GetData(Figure)

handles = guidata(Figure);

% Graphics
Lines = findall(handles.Axes,'Type','Line');
if isempty(Lines)
    return
end
L = numel(Lines);

Tau      = get(Lines(L),'Xdata')';
Data     = get(handles.UItable_noise,'Data');
ADEV     = get(Lines(L),'Ydata')';
Template = [];
Sum      = [];

% Template
if L == 3
    
    % Models
    Template = zeros(length(ADEV),1);
    for i = 1:size(Data,1)
        alpha = Data(i,1);
        tau_min = Data(i,2);
        tau_max = Data(i,3);
        k = Data(i,4);
        I = ge(Tau,tau_min) & le(Tau,tau_max);
        Template(I) = k * Tau(I) .^ alpha;
    end
    
    % Sum of models
    Sum = get(Lines(1),'Ydata')';
    
    % Non  null values
    I = ADEV~=0;
    ADEV = ADEV(I);
    Tau  = Tau(I);
    Template = Template(I);
    Sum = Sum(I);
    
end

% AVAR
ADEVs.Tau      = Tau; 
ADEVs.ADEV     = ADEV; 
ADEVs.Data     = Data;
ADEVs.Template = Template;
ADEVs.Sum      = Sum;

end
